package ewu

import ewu._
import ewu.expressions.ExpArray
import java.util.ArrayList
import scala.collection.mutable.HashMap
import scala.collection.mutable.ArrayBuffer

/**
 * Die functionExpression stellt einen Funktionsausdruck dar.
 * Dazu wird der Funktionsname als "name" definiert, sowie
 * die zu der Funktion zugehoerigen Parameter in einem Array
 * von Expression "params" abgelegt.
 */

case class functionExpression(name:String,
                              params:Array[Expression])
                                extends Expression{
  var initconf:Konfiguration = null;
  var funcconf:Konfiguration = null;
  var allvars:HashMap[Int, String] = null;
  var inputvars:Environment = null;
  var outputvars:Environment = null;
  var varsrelateoninput:HashMap[Name, Expression] = null;
  var arrayvars:ArrayList[String] = null;
  
  override def toString: String =
    name+"("+params.mkString(", ")+")"

  def toEvalString(env: Environment): String = {
    var str = name + "("
    for(i <- 0 to params.length-1) {
      var tmpstr = params(i).evaluate(env) match {
        case Some(x:BigInt) => 
          if(x == BigInt(298171879)) {
            if(params(i).isInstanceOf[Name]) {
              var tet:Expression = env.getArray(params(i).asInstanceOf[Name]) match {
                case x:ExpArray => x
                case _ => null
              }
              if(tet == null)
                Number(BigInt(0))
              else
                tet
            }
            else
              Number(BigInt(0))
          }
          else
            Number(x) 
        case None => Number(BigInt(0))
      }
      str += tmpstr
      if(i != params.length-1)
        str += ", "
    }
    str += ")"
    return str
  }
  
  def reduce: Expression = this
  //TODO evaluate functionExpression: uebergabe einer konfiguration beim erzeugen des Objekts, Konfiguration wird zum evaluieren verwendet
  def evaluate(a:Environment) = None
  
  def getVariables(a: ArrayBuffer[Name]) = {
    for(i <- params) {
      if(i.isInstanceOf[Name]) {
        if(!a.contains(i))
          a.append(i.asInstanceOf[Name])
      }
      else {
        i.getVariables(a)
      }  
    }
  }
  
  def replaceVariable(fromVar: Name, toVar: Expression) : Unit = {
    for(i <- params) {
      i.replaceVariable(fromVar, toVar)
    }
  }
  
  def setFuncConf(conf: Konfiguration) = {
    funcconf = conf
  }
}